package com.authine.cloudpivot.web.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.common.utils.StringUtils;
import com.authine.cloudpivot.web.api.dao.HEMSProfessionalMapper;
import com.authine.cloudpivot.web.api.service.ProfessionalService;
import com.authine.cloudpivot.web.api.utils.DateUtils;
import com.authine.cloudpivot.web.api.utils.HttpClients;
import com.authine.cloudpivot.web.api.vo.HEMSProfessional;
import com.authine.cloudpivot.web.api.vo.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * ClassName: ProfessionalServiceImpl <br/>
 * Description: 职员基本信息添加或更新<br/>
 * date: 2020/8/25 11:23<br/>
 * @author fj<br />
 * @since JDK 1.8
 */

@Slf4j
@Service
public class ProfessionalServiceImpl implements ProfessionalService {

    @Value("${basic.maxSequenceNoLength}")
    private Integer maxSequenceNoLength;
    @Value("${basic.adminId}")
    private String adminId;
    @Value("${basic.adminDeptId}")
    private String adminDeptId;
    @Value("${basic.professionalUrl}")
    private String professionalUrl;
    @Value("${basic.webServiceUsername}")
    private String webServiceUsername;
    @Value("${basic.webServicePassword}")
    private String webServicePassword;
    @Autowired
    private HEMSProfessionalMapper hemsProfessionalMapper;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private DefaultTransactionDefinition defaultTransactionDefinition;

    @Override
    public int addOrUpdateProfessional(int hours) {
        int num = 0;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.00");
        // 获取当前时间减去24小时之后的时间
        String dateTime = format.format(DateUtils.addDay(new Date(), 0 - hours));
        // 拼接professionalUrl，参数加上时间
        String url = professionalUrl + dateTime;
        // 获取最大单据号
        String sequenceNo = hemsProfessionalMapper.selectMaxSequenceNo();
        if (StringUtils.isNullOrEmpty(sequenceNo)){
            num = ResultCode.init_error;
            return num;
        }
        Integer maxSequenceNo = Integer.valueOf(sequenceNo.substring(sequenceNo.length()-maxSequenceNoLength));
        log.info("请求webservice接口地址url：{}，需要认证的用户名信息：{}，需要认证的密码信息：{}", url, webServiceUsername, webServicePassword);
        // 请求webservice接口，获取职员信息
        String result = HttpClients.getByBasicAuth(url, webServiceUsername, webServicePassword);
        log.info("请求webservice返回结果：{}", JSON.parseObject(result));
        JSONArray professionalList = new JSONArray();
        // 事务隔离级别，开启新事务
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 手动开启事物
        TransactionStatus transactionStatus = null;
        try {
            transactionStatus = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);
            // result不为空时，说明请求到了数据
            if (!StringUtils.isNullOrEmpty(result)) {
                JSONObject jsonObject = JSON.parseObject(result);
                if (jsonObject.containsKey("data")) {
                    HEMSProfessional insertProfessional = new HEMSProfessional();
                    HEMSProfessional updateProfessional = new HEMSProfessional();
                    insertProfessional.setCreater(adminId);
                    insertProfessional.setModifier(adminId);
                    insertProfessional.setOwner(adminId);
                    insertProfessional.setOwner(adminId);
                    insertProfessional.setCreateddeptid(adminDeptId);
                    insertProfessional.setOwnerdeptid(adminDeptId);
                    insertProfessional.setWorkflowinstanceid("");
                    insertProfessional.setOwnerdeptquerycode("");
                    insertProfessional.setSequencestatus("COMPLETED");
                    professionalList.addAll(jsonObject.getJSONArray("data"));
                    JSONObject links = jsonObject.getJSONObject("links");
                    boolean next = links.getString("next") != null;
                    if (next) {
                        url = links.getString("next");
                    }
                    // 如果next值不为空，说明还有数据，则一直循环请求接口
                    while (next) {
                        log.info("请求webservice接口地址url：{}，需要认证的用户名信息：{}，需要认证的密码信息：{}", url, webServiceUsername, webServicePassword);
                        result = HttpClients.getByBasicAuth(url, webServiceUsername, webServicePassword);
                        log.info("请求webservice返回结果：{}", JSON.parseObject(result));
                        jsonObject = JSON.parseObject(result);
                        professionalList.addAll(jsonObject.getJSONArray("data"));
                        links = jsonObject.getJSONObject("links");
                        if (links.getString("next") == null) {
                            next = false;
                        } else {
                            url = links.getString("next");
                        }
                    }
                    HEMSProfessional professional = null;
                    // 遍历数据，进行添加或者更新
                    if (professionalList.size() > 0) {
                        String year = DateUtils.getYear(new Date());
                        for (int i = 0; i < professionalList.size(); i++) {
                            jsonObject = professionalList.getJSONObject(i);
                            // 通过主键查询当前职员是否存在于数据库中，如果存在更新数据信息，不存在添加数据信息
                            professional = hemsProfessionalMapper.selectByProfessionalCode(jsonObject.getJSONObject("fields").getString("external_id"));
                            // 职员存在，数据更新
                            if (professional != null) {
                                updateProfessional.setId(professional.getId());
                                updateProfessional.setModifiedtime(new Timestamp(new Date().getTime()));
                                updateProfessional.setProfessionalname(jsonObject.getJSONObject("fields").getString("name"));
                                updateProfessional.setHospitalcode(jsonObject.getJSONObject("fields").getString("hospital_code"));
                                updateProfessional.setHospitalname(jsonObject.getJSONObject("fields").getString("hospital_name"));
                                updateProfessional.setStandarddepartment(jsonObject.getJSONObject("fields").getJSONObject("standard_department").getString("label"));
                                updateProfessional.setGender(jsonObject.getJSONObject("fields").getJSONObject("gender").getString("label"));
                                updateProfessional.setAdministratortitle(jsonObject.getJSONObject("fields").getJSONObject("administrator_title").getString("label"));
                                updateProfessional.setProfessionaltitle(jsonObject.getJSONObject("fields").getJSONObject("professional_title").getString("label"));
                                updateProfessional.setAcademictitle(jsonObject.getJSONObject("fields").getJSONObject("picklist_6").getString("label"));
                                updateProfessional.setName(updateProfessional.getProfessionalname());
                                num = hemsProfessionalMapper.updateByPrimaryKeySelective(updateProfessional);
                                log.info("update isrv4_HEMS_Professional，updateProfessional：{}，result：{}", updateProfessional, num);
                                if (num == 1) {
                                    num = 0;
                                } else {
                                    num = ResultCode.update_error;
                                    break;
                                }
                            } else {// 职员不存在，数据新增
                                insertProfessional.setId(UUID.randomUUID().toString());
                                insertProfessional.setCreatedtime(new Timestamp(new Date().getTime()));
                                insertProfessional.setModifiedtime(insertProfessional.getCreatedtime());
                                maxSequenceNo++;
                                insertProfessional.setSequenceno(year + "-" + String.format("%0" + maxSequenceNoLength + "d", maxSequenceNo));
                                insertProfessional.setProfessionalcode(jsonObject.getJSONObject("fields").getString("external_id"));
                                insertProfessional.setProfessionalname(jsonObject.getJSONObject("fields").getString("name"));
                                insertProfessional.setHospitalcode(jsonObject.getJSONObject("fields").getString("hospital_code"));
                                insertProfessional.setHospitalname(jsonObject.getJSONObject("fields").getString("hospital_name"));
                                insertProfessional.setStandarddepartment(jsonObject.getJSONObject("fields").getJSONObject("standard_department").getString("label"));
                                insertProfessional.setGender(jsonObject.getJSONObject("fields").getJSONObject("gender").getString("label"));
                                insertProfessional.setAdministratortitle(jsonObject.getJSONObject("fields").getJSONObject("administrator_title").getString("label"));
                                insertProfessional.setProfessionaltitle(jsonObject.getJSONObject("fields").getJSONObject("professional_title").getString("label"));
                                insertProfessional.setAcademictitle(jsonObject.getJSONObject("fields").getJSONObject("picklist_6").getString("label"));
                                insertProfessional.setName(updateProfessional.getProfessionalname());
                                num = hemsProfessionalMapper.insertSelective(insertProfessional);
                                log.info("insert isrv4_HEMS_Professional，insertProfessional：{}，result：{}", insertProfessional, num);
                                if (num == 1) {
                                    num = 0;
                                } else {
                                    num = ResultCode.insert_error;
                                    break;
                                }
                            }
                        }
                        if (num == 0) {
                            dataSourceTransactionManager.commit(transactionStatus);
                        } else {
                            dataSourceTransactionManager.rollback(transactionStatus);
                        }
                        professionalList = null;
                        insertProfessional = null;
                        updateProfessional = null;
                    }
                }
            }
        } catch (Exception e) {
            if (transactionStatus != null){
                dataSourceTransactionManager.rollback(transactionStatus);
            }
            num = ResultCode.network_error;
        }
        return num;
    }
}
